#include <cserver/session/timer.h>
#include <cserver/context.h>
#include <boost/log/trivial.hpp>
namespace csrv{
	WallTimer::WallTimer(Context& ctx)
	: context(ctx)
	, sys_timer(ctx.ios_aserver)
	{}
	void WallTimer::start(){
		boost::asio::spawn(context.ios_aserver, [&](boost::asio::yield_context yield) { run_(yield);});
	}

	void WallTimer::append(boost::asio::system_timer::time_point tp, std::function<void()> f){
		timers[tp].push_back(f);
		sys_timer.cancel();
	}
	void WallTimer::run_(boost::asio::yield_context yield){
		for(;;){
			BOOST_LOG_TRIVIAL(info) << "Timer Entered.";
			auto tp  = std::chrono::system_clock::now();
			auto itr = timers.begin();
			for(;itr != timers.end(); ++itr){
				if (itr->first <= tp)
					for(auto& f : itr->second)
						f();
				else break;
			}
			timers.erase(timers.begin(), itr);

			if (!timers.empty())
				tp = timers.begin()->first;
			else
				tp += std::chrono::hours(1);

			sys_timer.expires_at(tp);
			boost::system::error_code ec;
			sys_timer.async_wait(yield[ec]);
			BOOST_LOG_TRIVIAL(info) << "Timer expired.";
		}
	}

}



